package com.stone.serverless.rpc.loadbalancer;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.Server;
import com.stone.serverless.registry.DiscoveryService;
import com.stone.serverless.rpc.RpcOkhttpComponentConsumer;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description: TODO
 * @Author: MECHREVO
 * @Date: 2022/1/25 14:46
 * @Version: 1.0.0
 */
public class StoneLoadBalancerRule extends AbstractLoadBalancerRule {
    @Override
    public Server choose(Object key) {
        ServerInfo serverInfo = (ServerInfo) key;
        DiscoveryService discoveryService = RpcOkhttpComponentConsumer.INSTANCE.discoveryService;
        if (null == discoveryService) {
            return null;
        }
        String version = serverInfo.getVersion();
        List<Server> reachableServers = this.getLoadBalancer().getReachableServers();
        List<Server> collect = reachableServers.stream().filter(v -> {
            StoneServer server = (StoneServer) v;
            //版本
            String s = server.getServiceInstance().getMetadata().get("service-version");
            return CharSequenceUtil.equals(s, version);
        }).collect(Collectors.toList());
        //匹配版本

        if (CollUtil.isEmpty(collect)) {
            return null;
        }

        return getHostByRandomWeight(collect);
    }

    @Override
    public void initWithNiwsConfig(IClientConfig clientConfig) {

    }

    protected static Server getHostByRandomWeight(List<Server> hosts) {
        if (hosts == null || hosts.size() == 0) {
            return null;
        }
        List<Pair<Server>> hostsWithWeight = new ArrayList<Pair<Server>>();
        for (Server host : hosts) {
            StoneServer server = (StoneServer) host;
            if (server.getServiceInstance().isHealthy()) {
                hostsWithWeight.add(new Pair(host, server.getServiceInstance().getWeight()));
            }
        }
        Chooser<String, Server> vipChooser = new Chooser<String, Server>("stone");
        vipChooser.refresh(hostsWithWeight);
        return vipChooser.randomWithWeight();
    }
}
